package cn.iocoder.yudao.module.currency.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ExchangeRateUtils {


    private static final String BASE_URL = "https://finance.pae.baidu.com/selfselect/sug?skip_login=1&finClientType=pc&wd=";

    private static final String SUCCESS = "0";

    public static void main(String[] args) {
        /*ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                fetchCurrencyExchange("USDCNY");
            }
        }, 0, 5, TimeUnit.MINUTES);*/

        System.out.println(fetchCurrencyExchange("USD", "CNY"));
    }

    public static ExchangeRateThirdDTO fetchCurrencyExchange(String baseCurrency, String targetCurrency) {
        log.info("通过第三方接口获取币种汇率, baseCurrency: {}, targetCurrency: {}", baseCurrency, targetCurrency);
        ExchangeRateThirdDTO exchange = fetchCurrencyExchange(baseCurrency + targetCurrency, ExchangeApiTypeEnum.BAIDU);
        log.info("通过第三方接口获取币种汇率, exchange: {}", exchange);
        return exchange;
    }

    private static ExchangeRateThirdDTO fetchCurrencyExchange(String code, ExchangeApiTypeEnum apiType) {
        switch (apiType) {
            case BAIDU:
                return fetchBaiduCurrencyExchange(code);
            default:
                return null;
        }
    }

    private static ExchangeRateThirdDTO fetchBaiduCurrencyExchange(String code) {
        try {
            String httpUrl = BASE_URL + code;

            HttpRequest httpRequest = HttpRequest.get(httpUrl);
            httpRequest.header("host", "finance.pae.baidu.com");
            httpRequest.header("origin", "https://gushitong.baidu.com");
            httpRequest.header("referer", "https://gushitong.baidu.com/");
            httpRequest.header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36");
            httpRequest.header("sec-ch-ua", "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\"");
            httpRequest.header("sec-ch-ua-mobile", "?0");
            httpRequest.header("sec-ch-ua-platform", "\"Windows\"");
            httpRequest.header("sec-fetch-dest", "empty");
            httpRequest.header("sec-fetch-mode", "cors");
            httpRequest.header("sec-fetch-site", "same-site");

            HttpResponse response = httpRequest.execute();
            if (response.isOk()) {
                return parseBaiduCurrencyExchange(response.body());
            } else {
                log.error("请求百度汇率接口HTTP状态异常, http status: {}", response.getStatus());
            }
        } catch (HttpException e) {
            log.error("请求百度汇率接口异常", e);
        }
        return null;
    }

    private static ExchangeRateThirdDTO parseBaiduCurrencyExchange(String str) {
        // {"QueryID":"2007449265","ResultCode":"0","Result":{"stock":[{"code":"USDCNY","type":"foreign","market":"global","follow_status":"0","name":"\u7f8e\u5143\u5151\u4eba\u6c11\u5e01","price":"7.1507","ratio":"+0.2900%","status":"1","increase":"+0.0204","exchange":"FX","volume":"--","capitalization":"--","turnoverRatio":"--","amplitudeRatio":"--","src_loc":"--","amount":"--","peRate":"--","pbRate":"--","stockStatusInfo":"--","holdingAmount":"--","subType":"--","sf_url":"\/sf?word=USDCNY&ext=%7B%22sf_tab_name%22%3A%22%5Cu6982%5Cu89c8%22%7D&title=%E7%BE%8E%E5%85%83%E5%85%91%E4%BA%BA%E6%B0%91%E5%B8%81&pd=new_stock&openapi=1&from_sf=1&dspName=iphone&name=%E7%BE%8E%E5%85%83%E5%85%91%E4%BA%BA%E6%B0%91%E5%B8%81&code=USDCNY&market=global&ma_ver=4","pv":"0","CNYPrice":"0"}],"index":[],"deal_status":"","stock_status":{"is_trend":"","time_sort":""},"refresh_time":"","labelMap":[{"text":"\u6da8\u8dcc\u5e45","ename":"ratio"},{"text":"\u6da8\u8dcc\u989d","ename":"increase"},{"text":"\u6210\u4ea4\u91cf","ename":"volume"},{"text":"\u603b\u5e02\u503c","ename":"capitalization"},{"text":"\u6362\u624b\u7387","ename":"turnoverRatio"},{"text":"\u632f\u5e45","ename":"amplitudeRatio"}],"isNew":"1","follow_num":"0"}}
        if (StringUtils.isNotBlank(str)) {
            JSONObject object = JSON.parseObject(str);
            String resultCode = object.getString("ResultCode");
            if (SUCCESS.equals(resultCode)) {
                ExchangeRateThirdDTO exchange = new ExchangeRateThirdDTO();
                JSONObject result = object.getJSONObject("Result");
                exchange.setNewResult(StringUtils.equals(result.getString("isNew"), "1"));
                JSONArray stockArray = result.getJSONArray("stock");
                if (CollectionUtil.isNotEmpty(stockArray)) {
                    JSONObject stock = stockArray.getJSONObject(0);
                    exchange.setPrice(new BigDecimal(stock.getString("price")));
                    String ratioStr = stock.getString("ratio");
                    exchange.setRatio(parseRate(ratioStr));
                    String increaseStr = stock.getString("increase");
                    exchange.setIncrease(parseRate(increaseStr));
                    return exchange;
                }
                log.error("请求百度汇率接口返回值异常, 没有stock数据, ResultCode: {}, response: {}", resultCode, str);
            } else {
                log.error("请求百度汇率接口返回值异常, ResultCode: {}, response: {}", resultCode, str);
            }
        } else {
            log.error("请求百度汇率接口返回结果为空");
        }
        return null;
    }

    private static BigDecimal parseRate(String str) {
        boolean downFlag = str.startsWith("-");
        if (str.startsWith("+") || str.startsWith("-")) {
            str = str.substring(1);
        }
        BigDecimal ratio;
        if (str.contains("%")) {
            str = str.substring(0, str.length() - 1);
            ratio = new BigDecimal(str).divide(new BigDecimal("100"), 8, BigDecimal.ROUND_HALF_UP);
        } else {
            ratio = new BigDecimal(str);
        }
        ratio = ratio.multiply(new BigDecimal(downFlag ? "-1" : "1"));
        return ratio;
    }

}
